C 风格字符串
C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。
下面的声明和初始化创建了一个 Oldmoon 字符串。
由于在数组的末尾存储了空字符,所以字符数组的大小比单词 Oldmoon 的字符数多一个。
char s1[8] = {'O','l','d','m','o','o','n','\0'};
依据数组初始化规则,您可以把上面的语句写成以下语句:
char s1[] = "Oldmoon";
输入输出方式
在 C 语言中,有函数可以让用户从键盘上输入字符串,它就是:
注意
- scanf():通过格式控制符%s 输入字符串。除了字符串,scanf() 还能输入其他类型的数据。
scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。
输入输出方式 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[30];
//请输入一个字符串
scanf("%s",s1);
printf("s1:%s",s1);
return 0;
}
运行结果:
```c
输入:
welcome oldmoon↙(表示输入结束)
输出:
s1: welcome
分析
使用 scanf 输入,遇到空格就认为当前字符串结束了,所以输入 welcome oldmoon,输出是 welcome。
- 为了解决上面得问题,我们可以这样修改:
scanf("%[^\n]",s) 能解决这个问题,一直读取,直到遇到\n 结束,空格当成普通字符读入。
输入输出方式 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[30];
//请输入一个字符串
scanf("%[^\\n]s",s1);
printf("s1:%s",s1);
return 0;
}
运行结果:
输入:
welcome oldmoon↙(表示输入结束)
输出:
s1: welcome oldmoon
分析
从输出上可以看出,空格当作普通字符读取了,直到遇到换行,字符串才结束
也可通过 C++中的cin进行输入
注意
对于一次 cin 调用,在没有读到非空白字符前它会将遇到的所有空白字符丢弃(不会停止读取),在读到非空白字符之后遇到空白字符 cin 将停止读取。
空白字符:所谓空白符其实就是空格、制表符、换行符的统称
C 风格字符串 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s4[30];
//输入一个字符串
cin >> s4 ;
cout << s4 << endl;
return 0;
}
运行结果:
输入一个字符串:welcome oldmmon↙(表示输入结束)
welcome
分析
跟 scanf 比较相像,遇到空格即结束,所以输入的 welcome oldmmon,最终输出的 welcome。
一定要多去尝试哦~
示例
C 风格字符串 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[] = "Oldmoon";
cout << "欢迎来到:" << s1 << endl;
return 0;
}
运行结果:
欢迎来到:Oldmoon
C 风格字符串 相关函数
常用函数
加上头文件 string.h 或 cstring
- strlen
- strcmp
- strcat
- strcpy
- memset
strlen
strlen(s1)
返回字符串 s1 的长度,长度不包含'\0'。
strlen 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[] = "Oldmoon";
cout << "字符串的长度是:" << strlen(s1) << endl;
return 0;
}
运行结果:
字符串的长度是:7
使用的是万能头,所以不需要加上头文件 string.h :::
strcmp
strcmp(s1,s2)
比较字符串 s1 和 s2。
若 s1 = s2,则返回零;若 s1 < s2,则返回负数;若 s1 > s2,则返回正数。
两个字符串自左向右逐个字符相比(按 ASCII 值大小相比较),直到出现不同的字符或遇'\0'为止。
strcmp 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[] = "Oldmoon";
char s2[] = "Oldmoon";
cout << "s1 和 s2 进行比较的结果: " << strcmp(s1,s2) << endl;
return 0;
}
运行结果:
s1 和 s2 进行比较的结果: -1(数值不固定,但是是负数)
答案是几不重要,重要的是负数,说明 s1 小于 s2
两个字符串自左向右逐个字符相比,O 跟 o 的 ASCII 值进行比较,O 小于 o,所以直接返回负数结果。
建议
尝试两个相同的字符串运行看看效果呦
strcat
strcat(s1,s2)
把 s2 所指向的字符串(包括"\0")复制到 s1 所指向的字符串后面(删除 s2 原来末尾的“\0”)。
要保证 s1 足够长,以容纳被复制进来的 s2。s2 中原有的字符不变。
strcat 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[20] = "welcome ";
char s2[20] = "Oldmoon";
strcat(s1,s2);
cout << "strcat(s1,s2): " << s1 << endl;
return 0;
}
运行结果:
strcat(s1,s2): welcome Oldmoon
s1 字符串的空间一定要要确保能放得下 s1 和 s2 :::
strcpy
strcpy(s1,s2)
把从 s2 地址开始且含有 NULL 结束符的字符串复制到以 s1 开始的地址空间
要保证 s1 必须有足够的空间来容纳 s2 的字符串。
strcpy 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s1[20] = "hello ";
char s2[20] = "Oldmoon";
strcpy(s1,s2);
cout << "strcpy(s1,s2): " << s1 << endl;
return 0;
}
运行结果:
strcpy(s1,s2): Oldmoon
s1 字符串的空间一定要要确保能放得下 s2。 :::
memset
memset(void *str, int c, size_t n)
复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符
str : 指向要填充的内存块。
c : 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
n : 要被设置为该值的字符数。
memset 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
char str[50] = "welcome,oldmoon" ;
memset(str,'$',7);
cout << str << endl;
return 0;
}
运行结果:
$$$$$$$,oldmoon
建议
memset 也慢慢的变成大家进行初始化的一种写法。
例如:
int arr[50];
memset(arr,0,sizeof(arr));
是一种将数组 arr 所有数据初始化为 0 的方式,写法简单。
拓展内容
以下为拓展内容
转义字符
转移字符 | 意义 |
---|---|
\a | 警告声 |
\b | 退回 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 水平 Tab |
\v | 垂直 Tab |
\\ | 右斜线 |
' | 单引号 |
" | 双引号 |
? | 问号 |
\0 | Null |
转义字符 示例代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
printf("You\\nare\\nlearning\\n\\'C++\\' language\\n\\t\\"Do you know C++language\\"");
return 0;
}